package cy.security.browser;

import cy.security.core.authentication.AbstractChannelSecurityConfig;
import cy.security.core.authentication.mobile.SmsCodeAuthenticationSecurityConfig;
import cy.security.core.authorize.AuthorizeConfigManager;
import cy.security.core.properties.SecurityConstants;
import cy.security.core.properties.SecurityProperties;
import cy.security.core.validate.code.ValidateCodeSecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.session.InvalidSessionStrategy;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;
import org.springframework.social.security.SpringSocialConfigurer;

import javax.sql.DataSource;

/**
 * @Author: ciyuan
 * @Date: 2019/5/17 22:14
 */
@Configuration
public class BrowserSecurityConfig extends AbstractChannelSecurityConfig {

    @Autowired
    private SecurityProperties securityProperties;


    @Autowired
    private DataSource dataSource;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;

    @Autowired
    private ValidateCodeSecurityConfig validateCodeSecurityConfig;

    @Autowired
    private SpringSocialConfigurer easySocialConfigurer;

    @Autowired
    private InvalidSessionStrategy invalidSessionStrategy;

    @Autowired
    private SessionInformationExpiredStrategy sessionInformationExpiredStrategy;

    @Autowired
    private LogoutSuccessHandler logoutSuccessHandler;

    @Autowired
    private AuthorizeConfigManager authorizeConfigManager;



    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        //启动的时候创建存储token的数据库表 初次启动项目时需要配置 创建完成之后可以把改行注释掉
//        tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        applyPasswordAuthenticationConfig(http);

        http.apply(validateCodeSecurityConfig)
                .and()
                .apply(smsCodeAuthenticationSecurityConfig)
                .and()
                .apply(easySocialConfigurer)
                .and()
                //配置记住“我的功能”
                .rememberMe()
                //配置持久化token的仓储组件
                .tokenRepository(persistentTokenRepository())
                //配置token过期的时间
                .tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds())
                //配置拿到用户信息之后登录的userDetailsService
                .userDetailsService(userDetailsService)
                .and()
                .sessionManagement()
                //配置session过期时的策略
                .invalidSessionStrategy(invalidSessionStrategy)
                //设置最大登录的用户数
                .maximumSessions(securityProperties.getBrowser().getSession().getMaximumSessions())
                //当登录的数量达到最大值时，阻止新用户的登录
                .maxSessionsPreventsLogin(securityProperties.getBrowser().getSession().isMaxSessionsPreventsLogin())
                //配置session并发策略
                .expiredSessionStrategy(sessionInformationExpiredStrategy)
                .and()
                .and()
                .logout()
                .logoutUrl("/signOut")
                //.logoutSuccessUrl("/logout.html")
                .logoutSuccessHandler(logoutSuccessHandler)
                .deleteCookies("JSESSIONID")
                .and()


//                .authorizeRequests()
//                //声明不需要登录验证的接口
//                .antMatchers(
//                        SecurityConstants.DEFAULT_UNAUTHENTICATION_URL,
//                        SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE,
//                        securityProperties.getBrowser().getLoginPage(),
//                        SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX + "/*",
//                        securityProperties.getBrowser().getSignUpUrl(),
//                        "/user/registered",
//                        securityProperties.getBrowser().getSession().getSessionInvalidUrl())
//                .permitAll()
//                .anyRequest()
//                .authenticated()
//                .and()


                .csrf().disable();

        authorizeConfigManager.config(http.authorizeRequests());
    }
}
